package com.refusea.remoting.alibaba

import com.refusea.commons.http.Https
import com.refusea.commons.http.Https.Companion.success
import com.refusea.commons.http.Https.Method.DELETE
import com.refusea.commons.http.Https.Method.HEAD
import com.refusea.commons.http.Https.Method.PUT
import com.refusea.remoting.alibaba.commons.AlibabaCommonHeaders


/**
 * @author Zhang Yan, 2023/9/7
 **/
object OssApi {

    private const val END_POINT = "oss-cn-shenzhen.aliyuncs.com"

    private val http = Https(3_000L, 20_000L)

    private val contentTypes: Map<String, List<Pair<String, String>>> = listOf(
        "jpg" to "image/jpeg",
        "jpeg" to "image/jpeg",
        "webp" to "image/webp",
        "heic" to "image/heic",
        "mp4" to "video/mp4",
        "png" to "image/png",
        "pdf" to "application/pdf",
        "zip" to "application/zip",
        "md" to "text/markdown",
    ).associate {
        it.first to listOf("Content-Type" to it.second)
    }

    /**
     * is object exist?
     *
     * @see <a href='https://help.aliyun.com/zh/oss/developer-reference/headobject?spm=a2c4g.11186623.0.0.548c4d96m6JRCh'>HeadObject</a> **/
    fun exist(bucket: String, key: String): Boolean {
        val url = "https://$bucket.$END_POINT/$key"
        val rsp = http.head(url, AlibabaCommonHeaders.authorization(HEAD, bucket, key))
        return rsp.success
    }

    fun put(
        bucket: String,
        key: String,
        content: ByteArray,
        contentType: String? = null,
        format: String? = null,
    ): Boolean {

        check(contentType != null || format != null) { "content-type or format can't be null together" }

        val url = "https://$bucket.$END_POINT/$key"
        val headers: List<Pair<String, String>> =
            if (contentType == null) {
                if (format == null) {
                    emptyList()
                } else {
                    contentTypes[format] ?: emptyList()
                }
            } else {
                listOf("Content-Type" to contentType)
            }
        val rsp = http.put(
            url, AlibabaCommonHeaders.authorization(PUT, bucket, key, headers), emptyList(), content
        )
        return rsp.success
    }

    fun delete(bucket: String, key: String): Boolean {
        val url = "https://$bucket.$END_POINT/$key"
        val rsp = http.delete(url, AlibabaCommonHeaders.authorization(DELETE, bucket, key))
        return rsp.success
    }
}
